
#ifndef AbstractClass_h
#define AbstractClass_h

#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "SOIL.lib")

#include <iostream>
#include <string>
#include "Utils\UtilsGL.h"
#include "Utils\Vector.h"


class AbstractClass {

public:
	AbstractClass(const char *title, int w, int h, int flags = 0);


	AbstractClass(int *argcp, char **argv, const char *title, int w, int h, int flags = 0);

	virtual ~AbstractClass();


	virtual int SetVideoMode(int w,int h,int flags = 0);

	virtual void SetTitle(const char *title);

	virtual void Run();

	virtual void ShowFPS(bool b){
		dispFPS=b;
	}

protected:
	bool dispPrint;

	bool getTimerReset;
	float curFPS;
	Vector2i windowSize;

	char textBuffer[500];

	////Timers
	void startTimer(){
		timerTime=glutGet(GLUT_ELAPSED_TIME);
	}

	long getTimer(){
		glFinish();

		long res=glutGet(GLUT_ELAPSED_TIME)-timerTime;

		if(getTimerReset)
			timerTime=glutGet(GLUT_ELAPSED_TIME);

		return res;
	}

	/** 
	  * Methode d'initialisation de l'application.
	  * A reimplementer par les applications clientes
	  */
	virtual void Init(){}
	
	/** Methodes de callback. */

	virtual void Idle() { }
	virtual void Display() { }
	virtual void PostDisplay();

	virtual void Reshape(int w, int h){}
	virtual void Keyboard(unsigned char key){}
	virtual void SpecialKey(int key){}
	virtual void Mouse(int button, int state, int x, int y){}
	virtual void MouseMove(int x, int y){}
	virtual void MousePassiveMove(int x, int y){}
	virtual void Update(int value){}
	virtual void Redisplay();
	//////


	/** Inversion des front et back buffers. */
	virtual void SwapBuffers();

private:
	
	static AbstractClass *currentApp;

	static void IdleFunc();
	static void DisplayFunc();
	static void ReshapeFunc(int w, int h);
	static void KeyboardFunc(unsigned char key, int x, int y);
	static void SpecialKeyFunc(int key, int x, int y);
	static void MouseFunc(int button, int state, int x, int y);
	static void MouseMotionFunc(int x, int y);
	static void MousePassiveMotionFunc(int x, int y);
	static void UpdateFunc(int value);


	std::string windowTitle;
	int windowFlags;
	int windowID;


	bool dispFPS;
	
	int lastFPSTime;
	int fpsCounter;
	int fpsCountInterval;

	long timerTime;


	std::string stayText;
	Vector2i stayTextPos;
	Vector4f stayTextColor;
	long stayTextTime;

	long lastFrameTime;
	long frameDuration;
};
#endif
